package animator.phantom.gui;

/*
    Copyright Janne Liljeblad 2006,2007,2008

    This file is part of Phantom2D.

    Phantom2D is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Phantom2D is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Phantom2D.  If not, see <http://www.gnu.org/licenses/>.
*/

import animator.phantom.plugin.*;
import animator.phantom.controller.*;
import animator.phantom.renderer.*;
import animator.phantom.renderer.param.*;
import animator.phantom.project.MovieFormat;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.util.*;

//--- Application menu.
public class AnimatorMenu extends JMenuBar implements ActionListener
{
	//--- File
	JMenuItem newProject;
	JMenuItem openProject;
	JMenuItem openRecent;
	JMenuItem saveProject;
	JMenuItem saveProjectAs;
	JMenuItem closeProject;

	JMenuItem exportFile;
	JMenuItem quit;

	//--- Edit
	JMenuItem undo;
	JMenuItem redo;
	JMenuItem projectSettings;
	JMenuItem projectInfo;
	JMenuItem importFileSettings;
	JMenuItem pluginSettings;
	JMenuItem editorPreferences;
	JMenuItem kfPreferences;
	JMenuItem keyboardShortcuts;

	//--- Node
	JMenuItem renameSelected;
	JMenuItem enableSelected;
	JMenuItem disableSelected;
	JMenuItem cloneSelected;

	//--- View
/*
	JMenuItem wideLayout;
	JMenuItem narrowLayout;
	JMenuItem iconView;
	JMenuItem listView;
	JMenuItem panelSettings;

*/	//--- bin
	JMenuItem addBin;
	JMenuItem deleteBin;
	JMenuItem renameBin;
	JMenuItem reloadSelected;
	JMenuItem replaceSelected;
/*
	//--- keyframe
	JMenuItem clearAll;
	JMenuItem freezeAll;
	JMenuItem addToAll;
	JMenuItem clearCurrent;
	JMenuItem removeAllAfter;
	JMenuItem scaleAllAfter;
	JMenuItem moveAllAfter;
	JMenuItem removeAllBefore;
*/


	//--- Tool
	JMenuItem activateSelected;
	JMenuItem deactivateSelected;

	//--- Render 
	JMenuItem frameOutputSettings;
	JMenuItem renderSettings;
	JMenuItem motionBlurSettings;
	JMenuItem threadsSettings;
	JMenuItem cacheSettings;
	JMenuItem previewCurrent;
	JMenuItem previewFromCurrent;
	JMenuItem previewFromStart;
	JMenuItem renderMovie;

	//--- Help
	JMenuItem codecInfo;
	JMenuItem about;

	//----
	private int SHORT_CUT_PLACE = 25;

	//---
	Vector<JMenuItem> newProjectItems = new Vector<JMenuItem>();

	public AnimatorMenu()
	{
		super();

		setFont( GUIResources.BASIC_FONT_12 );

		//---------------------------------- File menu
		JMenu fileMenu = new JMenu("File");
		//JMenu fileMenu = new JMenu( GUILang.get("TESTING") );
		//----
		JMenu newSelect = new JMenu( "New" );
		JMenuItem customItem = new JMenuItem( "custom" );
		customItem.addActionListener(this);
		newSelect.add( customItem );
		newProjectItems.add( customItem );
		for( int i = 0; i < MovieFormat.formats.size(); i++ )
		{
			
			JMenuItem addItem = new JMenuItem( MovieFormat.formats.elementAt( i ).getName() );
			addItem.addActionListener(this);
			newSelect.add( addItem );
			newProjectItems.add( addItem );
		}
		fileMenu.add( newSelect );
		//---
		openProject = new JMenuItem("Open...");
		openProject.addActionListener(this);
		fileMenu.add(openProject);
		//---
		openRecent = new JMenu( "Open Recent" );
		updateRecentMenu();
		fileMenu.add(openRecent);
		//---	
		fileMenu.addSeparator();
		//---
		saveProject = new JMenuItem( "Save" );
		saveProject.setAccelerator( KeyStroke.getKeyStroke( "ctrl pressed S"  ) );
		saveProject.addActionListener(this);
		fileMenu.add(saveProject);
		//---
		saveProjectAs = new JMenuItem("Save As...");
		saveProjectAs.addActionListener(this);
		fileMenu.add(saveProjectAs);
		//---	
		//---

		//---
		exportFile = new JMenuItem( "Export" );
		exportFile.addActionListener(this);
		//fileMenu.add(exportFile);
		//---	
		fileMenu.addSeparator();
		//---
		closeProject = new JMenuItem( "Close" );
		closeProject.addActionListener(this);
		fileMenu.add( closeProject );
		//---
		quit = new JMenuItem( "Quit" );
		quit.addActionListener(this);
		quit.setAccelerator( KeyStroke.getKeyStroke( "ctrl pressed Q"  ) );
		fileMenu.add( quit );

		//------------------------------------ Edit menu
		JMenu editMenu = new JMenu("Edit");
		//--- 
		undo = new JMenuItem("Undo");
		undo.addActionListener(this);
		undo.setAccelerator( KeyStroke.getKeyStroke( "ctrl pressed Z"  ) );
		editMenu.add( undo );
		//---
		redo = new JMenuItem("Redo");
		redo.addActionListener(this);
		redo.setAccelerator( KeyStroke.getKeyStroke( "ctrl shift pressed Z"  ) );
		editMenu.add( redo );
		//---	
		editMenu.addSeparator();
		//---
		projectSettings = new JMenuItem("Project Settings...");
		projectSettings.addActionListener(this);
		editMenu.add( projectSettings);

		projectInfo  = new JMenuItem("Project Info...");
		projectInfo.addActionListener(this);
		editMenu.add( projectInfo );
		//---	
		editMenu.addSeparator();
		//---
		importFileSettings = new JMenuItem( "Import Settings..." );
		importFileSettings.addActionListener(this);
		editMenu.add(importFileSettings);
		//---
		pluginSettings = new JMenuItem( "Plugin Settings.." );
		pluginSettings.addActionListener(this);
		editMenu.add(pluginSettings);
		//---	
		editMenu.addSeparator();
		//---
		editorPreferences= new JMenuItem("Editor Preferences...");
		editorPreferences.addActionListener(this);
		editMenu.add( editorPreferences );
		//---
		kfPreferences = new JMenuItem("Keyframe preferences...");
		kfPreferences.addActionListener(this);
		editMenu.add( kfPreferences );
		//---
		keyboardShortcuts = new JMenuItem("Keyboard Shortcuts...");
		keyboardShortcuts.addActionListener(this);
		editMenu.add( keyboardShortcuts );

		//------------------------------------ View menu
/*
		JMenu viewMenu = new JMenu("View");
		//---
		JMenu layoutSelect = new JMenu("Applacation layout");
		viewMenu.add( layoutSelect );
		ButtonGroup layoutGroup = new ButtonGroup();
		//--- 
		wideLayout = new JRadioButtonMenuItem("Wide screen layout");
		wideLayout.addActionListener(this);
		wideLayout.setSelected(true);
		layoutGroup.add( wideLayout );
		layoutSelect.add( wideLayout );
		//--- 
		narrowLayout = new JRadioButtonMenuItem("Narrow screen layout");
		narrowLayout.addActionListener(this);
		layoutGroup.add( narrowLayout );
		layoutSelect.add( narrowLayout );
		//---
		JMenu binViewSelect = new JMenu("Bin view");
		viewMenu.add( binViewSelect );
		ButtonGroup viewGroup = new ButtonGroup();
		//---
		iconView = new JRadioButtonMenuItem( "Icon view" );
		iconView.addActionListener(this);
		iconView.setSelected( true );
		viewGroup.add( iconView );
		binViewSelect.add( iconView );

		//---
		listView = new JRadioButtonMenuItem( "List view" );
		listView.addActionListener(this);
		viewGroup.add( listView );
		binViewSelect.add( listView );
		//---
		panelSettings = new JMenuItem("Window manager settings");
		panelSettings.addActionListener(this);
		viewMenu.add( panelSettings );
*/
		//---------------------------------- Bin menu
		JMenu binMenu = new JMenu("Bin");
		addBin = new JMenuItem("Create new Bin...");
		addBin.addActionListener(this);
		binMenu.add( addBin );
		//---
		deleteBin = new JMenuItem( "Delete current Bin" );
		deleteBin.addActionListener(this);
		binMenu.add( deleteBin );
		//---
		renameBin = new JMenuItem( "Rename current Bin..." );
		renameBin.addActionListener(this);
		binMenu.add( renameBin );
		//---
		binMenu.addSeparator();
		//---
		reloadSelected = new JMenuItem( "Reload selected files" );
		reloadSelected.addActionListener(this);
		binMenu.add( reloadSelected );
		//---
		replaceSelected = new JMenuItem( "Replace selected file..." );
		replaceSelected.addActionListener(this);
		binMenu.add( replaceSelected );

		//------------------------------------ Node menu
		JMenu iopMenu = new JMenu("Node");
		//---
		renameSelected = new JMenuItem("Rename...");
		renameSelected.addActionListener(this);
		iopMenu.add( renameSelected );
		//---
		cloneSelected = new JMenuItem("Clone");
		cloneSelected.addActionListener(this);
		iopMenu.add( cloneSelected );
		//---
		enableSelected = new JMenuItem("Enable");
		enableSelected.addActionListener(this);
		iopMenu.add( enableSelected );
		//---
		disableSelected = new JMenuItem("Disable");
		disableSelected.addActionListener(this);
		iopMenu.add( disableSelected );
		//---	
		iopMenu.addSeparator();
		buildIOPMenu( iopMenu );

		//------------------------------------ Keyframe
/*
		JMenu keyframeMenu = new JMenu("Keyframe");
		//---
		clearAll = new JMenuItem("Clear All");
		clearAll.addActionListener(this);
		keyframeMenu.add( clearAll );
		//---
		freezeAll = new JMenuItem("Freeze All To Current");
		freezeAll.addActionListener(this);
		keyframeMenu.add( freezeAll );
		//---
		addToAll = new JMenuItem("Add To All In Current");
		addToAll.addActionListener(this);
		keyframeMenu.add( addToAll );
		//---
		keyframeMenu.addSeparator();
		//---
		clearCurrent = new JMenuItem("Clear In Current");
		clearCurrent.addActionListener(this);
		keyframeMenu.add( clearCurrent );
		//---
		removeAllAfter = new JMenuItem("Clear After Current");
		removeAllAfter.addActionListener(this);
		keyframeMenu.add( removeAllAfter );
		//---
		removeAllBefore = new JMenuItem("Clear Before Current");
		removeAllBefore.addActionListener(this);
		keyframeMenu.add( removeAllBefore );
		//---
		keyframeMenu.addSeparator();
		//---
		moveAllAfter = new JMenuItem("Move After Current...");
		moveAllAfter.addActionListener(this);
		keyframeMenu.add( moveAllAfter );
		//---
		scaleAllAfter = new JMenuItem("Scale After Current...");
		scaleAllAfter.addActionListener(this);
		keyframeMenu.add( scaleAllAfter );
		//---
		keyframeMenu.addSeparator();
		//---
		kfPreferences = new JMenuItem("Keyframe preferences...");
		kfPreferences.addActionListener(this);
		keyframeMenu.add( kfPreferences );
*/
		//--- ------------------------------- Render menu
		JMenu renderMenu = new JMenu("Render");
		//---
		frameOutputSettings = new JMenuItem("Frame output...");
		frameOutputSettings.addActionListener(this);
		renderMenu.add( frameOutputSettings );
		//---
		renderSettings = new JMenuItem("Quality and Encoding...");
		renderSettings.addActionListener(this);
		renderMenu.add( renderSettings );
		//---
		motionBlurSettings = new JMenuItem("Motion Blur...");
		motionBlurSettings.addActionListener(this);
		renderMenu.add( motionBlurSettings );
		//---
		threadsSettings = new JMenuItem("Threads and Blenders...");
		threadsSettings.addActionListener(this);
		renderMenu.add( threadsSettings );
		//---
		cacheSettings = new JMenuItem("Cache...");
		cacheSettings.addActionListener(this);
		renderMenu.add( cacheSettings );
		//---
		renderMenu.addSeparator();
		//---
		previewFromCurrent = new JMenuItem("Preview From Current" );
		previewFromCurrent.addActionListener(this);
		previewFromCurrent.setAccelerator( KeyStroke.getKeyStroke( "F19"  ) );
		renderMenu.add( previewFromCurrent );
		//---
		previewFromStart = new JMenuItem("Preview From Start" );
		previewFromStart.addActionListener(this);
		previewFromStart.setAccelerator( KeyStroke.getKeyStroke( "F10"  ) );
		renderMenu.add( previewFromStart );
		//---
		previewCurrent = new JMenuItem("Preview current Frame" );
		previewCurrent.addActionListener(this);
		previewCurrent.setAccelerator( KeyStroke.getKeyStroke( "F11"  ) );
		renderMenu.add( previewCurrent );
		//---
		renderMenu.addSeparator();

		renderMovie = new JMenuItem("Render...");
		renderMovie.addActionListener(this);
		renderMovie.setAccelerator( KeyStroke.getKeyStroke( "F12"  ) );
		renderMenu.add( renderMovie );


		//----------------------------------- Help menu	
		JMenu helpMenu = new JMenu("Help");
		//--- 
		codecInfo = new JMenuItem("Codec Info");
		codecInfo.addActionListener(this);
		helpMenu.add( codecInfo );
		//---
		helpMenu.addSeparator();
		//--- 
		about = new JMenuItem("About Phantom2D");
		about.addActionListener(this);
		helpMenu.add( about );

		add( fileMenu );
		add( editMenu );
		add( binMenu );
		add( iopMenu );
		//add( keyframeMenu );
		add( renderMenu );
		add( helpMenu );
	}
	
	//--- Goes throung all item and sets fonts.
	private void setFont()
	{
		Component[] menus = getComponents();
		for( int i = 0; i <  menus.length; i++ )
		{
			JMenu menu = (JMenu) menus[ i ];
			setMenuFont( menu );
		}
	}
	//--- Goes through recursively submenus and set fonts.
	private void setMenuFont( JMenu menu )
	{
		menu.setFont( GUIResources.BASIC_FONT_12 );
		Component[] items = menu.getComponents();
		for( int j = 0; j < menu.getItemCount() ; j++ )
		{
			JMenuItem item = menu.getItem( j );
			if( item == null ) continue;
			item.setFont( GUIResources.BASIC_FONT_12 );
			if( item instanceof JMenu ) setMenuFont( (JMenu) item );
		}
	}
	//--- Adds key short cut to give place in string
	private String getItemString( String item, String shortCut, int correction )
	{
		int middleStringLength = SHORT_CUT_PLACE - item.length() + correction;
		StringBuffer rBuf = new StringBuffer(item);
		for( int i = 0; i < middleStringLength; i++ ) rBuf.append(" ");
		rBuf.append( shortCut );
		return rBuf.toString();
	}

	//--- Builds "ImageOperation" menu using input from IOPLibrary
	private void buildIOPMenu( JMenu iopMenu )
	{
		Vector<String> groups = IOPLibrary.getGroupKeys();
		for( String group : groups )
		{
			Vector iops = IOPLibrary.getGroupContents( group );
			Collections.sort( iops );
			JMenu subMenu = new JMenu( getItemString( group,"",0 ));
			for( int j = 0; j < iops.size(); j++ )
			{
				Object o = iops.elementAt( j );
				IOPMenuItem item = null;
				if( o instanceof ImageOperation )
				{
					ImageOperation iop = (ImageOperation) o;
					item = new IOPMenuItem( iop.getName(), iop.getClass().getName() );	
				}
				else
				{
					PhantomPlugin p = (PhantomPlugin) o;
					item = new IOPMenuItem( p.getIOP().getName(), p.getClass().getName() );
				}
				item.addActionListener(this);
				subMenu.add( item );
			}
			iopMenu.add( subMenu );
		}
	}
	
	public void updateRecentMenu()
	{
		openRecent.removeAll();
		Vector<File> recents = EditorPersistance.getRecentProjects();
		if( recents.size() == 0 )
		{
			RecentMenuItem none = new RecentMenuItem("none", null);
			none.setEnabled( false );
			openRecent.add( none );
		}
		else
		{
			for( File f : recents )
			{
				RecentMenuItem addr = new RecentMenuItem( f.getName(), f );
				addr.addActionListener(this);
				openRecent.add( addr );
			}
		}
	}
	
	//--------------------------------------------- MENU ACTIONS
	public void actionPerformed(ActionEvent e) 
	{
		//-------------------------------------------- File menu
		for( int i = 0; i < newProjectItems.size(); i++ )
		{
			if( e.getSource() == newProjectItems.elementAt( i ) )
			{
				MenuActions.newProject( i );
				return;
			}
		}
		if( e.getSource() == openProject ) MenuActions.openProject();
		if( e.getSource() instanceof RecentMenuItem )
		{
			RecentMenuItem r = ( RecentMenuItem )e.getSource();
			if( r.getFile() == null ) return;
			MenuActions.openProjectFile( r.getFile() );
			return;
		}
		if( e.getSource() == saveProject ) MenuActions.saveProject();
		if( e.getSource() == saveProjectAs ) MenuActions.saveProjectAs();
		if( e.getSource() == importFileSettings ) UserActions.setImportSettings();
		if( e.getSource() == pluginSettings ) MenuActions.setPluginSettings();
		if( e.getSource() == closeProject ) MenuActions.close();
		if( e.getSource() == quit ) MenuActions.quit();

		//--------------------------------------------- Edit menu
		if( e.getSource() == undo ) MenuActions.undo();
		if( e.getSource() == redo ) MenuActions.redo();
		if( e.getSource() == projectSettings ) MenuActions.setProjectProperties();
		if( e.getSource() == projectInfo ) MenuActions.showProjectInfo();
		if( e.getSource() == editorPreferences ) MenuActions.setEditorPreferences();
		if( e.getSource() == kfPreferences ) MenuActions.keyframePreferences();
		if( e.getSource() == keyboardShortcuts  ) MenuActions.setKeyboardShortcuts();

		//---------------------------------------------- Bin menu
		if( e.getSource() == addBin ) MenuActions.addBin();
		if( e.getSource() == deleteBin ) MenuActions.deleteBin();
		if( e.getSource() == renameBin ) MenuActions.renameBin();
		if( e.getSource() == reloadSelected ) MenuActions.reloadSelected();
		if( e.getSource() == replaceSelected ) MenuActions.replaceSelected();

		//---------------------------------------------- Bin menu
		if( e.getSource() == renameSelected ) MenuActions.renameSelected();
		if( e.getSource() == cloneSelected ) MenuActions.cloneSelected();
		if( e.getSource() == disableSelected ) MenuActions.disableSelected();
		if( e.getSource() == enableSelected ) MenuActions.enableSelected();

		//-------------------------------------------------- Render menu.
		if( e.getSource() == frameOutputSettings ) MenuActions.setFrameOutputSettings();
		if( e.getSource() == renderSettings ) MenuActions.setRenderSettings();
		if( e.getSource() == motionBlurSettings ) MenuActions.setMotionBlur();
		if( e.getSource() == threadsSettings ) MenuActions.setThreadsAndBlenders();
		if( e.getSource() == cacheSettings ) MenuActions.setCacheSettings();
		if( e.getSource() == previewCurrent ) PreviewController.renderAndDisplayCurrent();
		if( e.getSource() == previewFromStart ) PreviewController.renderAndPlayRange( 0, ProjectController.getLength() - 1 );
		if( e.getSource() == previewFromCurrent ) PreviewController.renderAndPlayRange( TimeLineController.getCurrentFrame(), ProjectController.getLength() - 1 );
		if( e.getSource() == previewFromStart )  PreviewController.renderAndPlayRange();
		if( e.getSource() == renderMovie ) RenderModeController.writeMovie();

		//--------------------------------------------------- ImageOperation
		if( e.getSource() instanceof IOPMenuItem )
		{
			IOPMenuItem source = ( IOPMenuItem )e.getSource();
			MenuActions.addIOP( source.getIopClassName() );
		}
/*
		//--------------------------------------------------- Keyframe
		if( e.getSource() == clearCurrent ) MenuActions.clearCurrent();
		if( e.getSource() == clearAll ) MenuActions.clearAll();
		if( e.getSource() == freezeAll ) MenuActions.freezeAllToCurrent();
		if( e.getSource() == addToAll ) MenuActions.addToAllInCurrent();
		if( e.getSource() == removeAllAfter ) MenuActions.clearAfterCurrent();
		if( e.getSource() == removeAllBefore ) MenuActions.clearBeforeCurrent();
		if( e.getSource() == scaleAllAfter ) MenuActions.scaleAfterCurrent();
		if( e.getSource() == moveAllAfter ) MenuActions.moveAfterCurrent();
		if( e.getSource() == kfPreferences ) MenuActions.keyframePreferences();
*/
		//----------------------------------------------------- Help menu
		if( e.getSource() == codecInfo ) MenuActions.displayCodecInfo();
		if( e.getSource() == about ) MenuActions.displayAbout();

	}

}//end class